package com.hileto.inf.utils.db;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.task.TaskExecutor;

import com.hileto.inf.utils.JsonHelp;
import com.hileto.inf.utils.ObjectHelp;

/**
 * Copyright: Copyright (c) 2012
 *     深圳市海乐淘电子商务有限公司
 * @Author : 曾林宝
 * @CreateTime : 2013-1-21 上午10:18:43
 *
 * @Description: 日志异步保存线程.
 */
public class InfoSaveThread implements Runnable,InitializingBean {
	static Map<String, BufferedWriter> writerMap = new HashMap<String, BufferedWriter>();
	static final SimpleDateFormat DATEFORMAT = new SimpleDateFormat("yyMMddHH");
	boolean isRunning = true;
	
	private int sleepTime = 1000;
	
	private String basePath ;
	private TaskExecutor taskExecutor;
	
	public InfoSaveThread() {
		if(isRunning){
			isRunning = false;
			if(ObjectHelp.isNotEmpty(basePath)){
				File root = new File(basePath);
				if (!root.exists()) {
					root.mkdirs();
				}
				isRunning = true;
			}
		}
	}
	
	public void setBasePath(String basePath) {
		this.basePath = basePath;
	}
	public void setSleepTime(int sleepTime) {
		this.sleepTime = sleepTime;
	}
	
	public void setIsRunning(boolean isRunning) {
		this.isRunning = isRunning;
	}

	public void setTaskExecutor(TaskExecutor taskExecutor) {
		this.taskExecutor = taskExecutor;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		if(null != taskExecutor && isRunning){
			taskExecutor.execute(this);
		}
	}

	@Override
	public void run() {
		List<Object> tmpList = new ArrayList<Object>();
		BufferedWriter out = null;
		String dateString = null;
		int sleepTimeTmp = this.sleepTime;
		while (true) {
			if (FileDB.isHasInfo && FileDB.dump(tmpList)) {
				dateString = DATEFORMAT.format(new Date());
				for (Object object : tmpList) {
					out = getBufferedWriter(object.getClass().getName(),dateString);
					try {
						out.write(JsonHelp.object2JsonSerializer(object));
						out.newLine();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if(!tmpList.isEmpty()){
					this.flushFileDB(dateString);
				}
			}
			try {
				Thread.sleep(sleepTimeTmp);
			} catch (InterruptedException e) {
			}
			if(FileDB.isShutdownThread()){
				return ;
			}
		}
	}

	private void flushFileDB(String dateString) {
		String key = null;
		BufferedWriter value = null;
		List<String> closeList = new ArrayList<String>();
		for (Entry<String, BufferedWriter> entry : writerMap.entrySet()) {
			value = entry.getValue();
			key = entry.getKey();
			try {
				value.flush();
				if(!key.endsWith(dateString + ".json")){
					value.close();
					closeList.add(key);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		for (String keyString : closeList) {
			writerMap.remove(keyString);
		}
	}

	private BufferedWriter getBufferedWriter(String clazz, String dateString) {
		BufferedWriter out = writerMap.get(clazz);
		if (null == out) {
			try {
				String path = basePath + clazz + "." + dateString + ".json";
				out = new BufferedWriter(new FileWriter(path, true));
				writerMap.put(clazz, out);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return out;
	}
}
